#include "Attribute.h"
#include "Screen.h"

namespace Horse
{
	BufferAttribute::BufferAttribute(const std::vector<float>& data, unsigned int position, unsigned int dimension)
		: m_data(data)
		, m_position(position)
		, m_dimension(dimension)
	{
	}
	void BufferAttribute::createOpenGLState(IScreen* screen)
	{
		screen->glGenBuffers(1, &m_vbo);
		screen->glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
		screen->glBufferData(GL_ARRAY_BUFFER, m_data.size() * sizeof(float), m_data.data(), GL_STATIC_DRAW);
		screen->glVertexAttribPointer(m_position, m_dimension, GL_FLOAT, false, m_dimension * sizeof(float), nullptr);
		screen->glEnableVertexAttribArray(m_position);
	}
	IndicesAttribute::IndicesAttribute(const std::vector<unsigned int>& indices)
		: m_indices(indices)
	{

	}
	void IndicesAttribute::createOpenGLState(IScreen* screen)
	{		
		screen->glGenBuffers(1, &m_ebo);
		screen->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
		screen->glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(unsigned int), m_indices.data(), GL_STATIC_DRAW);
	}
	void AttributeBuilder::addBuilder(const QString& key, const std::function<BufferAttribute* (Attribute*)>& builder)
	{
		std::map<QString, std::function<BufferAttribute* (Attribute*)>>::iterator iterator = m_attributeBuilders.find(key);
		if (iterator == m_attributeBuilders.cend())
		{
			m_attributeBuilders.insert({ key, builder });
		}
	}
	std::function<BufferAttribute* (Attribute*)> AttributeBuilder::getBuilder(const QString& key)
	{
		std::map<QString, std::function<BufferAttribute* (Attribute*)>>::iterator iterator = m_attributeBuilders.find(key);
		if (iterator != m_attributeBuilders.cend())
		{
			return iterator->second;
		}
		return [](Attribute*) ->BufferAttribute* { return nullptr; };
	}
	AttributeBuilder* AttributeBuilder::attributeBuilder()
	{
		static AttributeBuilder* attributeBuilder = new AttributeBuilder();
		return attributeBuilder;
	}
}